package com.happycat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.happycat.base.R;
import com.happycat.base.context.BaseContextHandler;
import com.happycat.base.exception.RestApiException;
import com.happycat.mapper.social.SocialVoiceRoomMapper;
import com.happycat.mobile.model.UserAccount;
import com.happycat.mobile.service.UserAccountService;
import com.happycat.social.dto.SocialVoiceRoomSaveDto;
import com.happycat.social.dto.SocialVoiceRoomUpdateDto;
import com.happycat.social.entity.SocialVoiceRoom;
import com.happycat.social.entity.SocialVoiceRoomAudit;
import com.happycat.social.entity.SocialVoiceRoomCategory;
import com.happycat.social.entity.SocialVoiceRoomWheat;
import com.happycat.social.service.*;
import com.happycat.social.vo.SocialVoiceRoomUserRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author jsonbin
 * @date 2020-09-10
 */
@Service
public class SocialVoiceRoomServiceImpl extends ServiceImpl<SocialVoiceRoomMapper, SocialVoiceRoom> implements ISocialVoiceRoomService {
    @Autowired
    private ISocialVoiceRoomCategoryService socialVoiceRoomCategoryService;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private ISocialVoiceRoomWheatService socialVoiceRoomWheatService;
    @Autowired
    private ISocialVoiceRoomAuditService socialVoiceRoomAuditService;
    @Autowired
    private ISocialVoiceRoomPermissionService socialVoiceRoomPermissionService;

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public SocialVoiceRoom applyRoom(SocialVoiceRoomSaveDto socialVoiceRoomSaveDto) {
        UserAccount userAccount = userAccountService.checkUserById(BaseContextHandler.getUserId());

        SocialVoiceRoomCategory category = null;
        if(socialVoiceRoomSaveDto.getRoomCategoryId()!=null && socialVoiceRoomSaveDto.getRoomCategoryId()!=0){
            //校验分类是否存在
            category = socialVoiceRoomCategoryService
                    .getById(socialVoiceRoomSaveDto.getRoomCategoryId());
            if(category==null){
                throw new RestApiException(R.fail("分类不存在"));
            }
        }

        //获取当前用户是否存在房间
        SocialVoiceRoom room = getOne(Wrappers.<SocialVoiceRoom>lambdaQuery()
                .eq(SocialVoiceRoom::getCreateAccountId, BaseContextHandler.getUserId()));

        if(room == null){
            //房间名称不能相同
            int count = count(Wrappers.<SocialVoiceRoom>lambdaQuery()
                    .eq(SocialVoiceRoom::getName, socialVoiceRoomSaveDto.getName()));
            if(count>=1){
                throw new RestApiException(R.fail("房间名已被使用"));
            }

            room = BeanUtil.copyProperties(socialVoiceRoomSaveDto, SocialVoiceRoom.class);
            room.setCreateAccountId(BaseContextHandler.getUserId());
            //生成房间号
            room.setRoomId(UUID.randomUUID().toString());
            room.setCreateAccountId(userAccount.getId());
            if(StrUtil.isBlank(userAccount.getImUserId())){
                userAccount.setImUserId(UUID.randomUUID().toString());
                userAccountService.updateById(userAccount);
            }
            room.setCreator(userAccount.getImUserId());

            room.setAuditStatus("1");//TODO 测试，修改为审批通过
            room.setValid("1");//一般默认有效
            room.setVisible("1");//TODO 测试，修改为审批通过
            room.setHot("0");
            room.setRecommend("0");
            if(socialVoiceRoomSaveDto.getRoomCategoryId()!=null && socialVoiceRoomSaveDto.getRoomCategoryId()!=0){
                room.setOfficial("1");
            }else {
                room.setOfficial("0");
            }

            room.setApplyNums(1);

            save(room);

            //新增审批记录
            saveAudit(socialVoiceRoomSaveDto, room);

            //新增主持人麦位
            SocialVoiceRoomWheat hostessW = new SocialVoiceRoomWheat();
            hostessW.setSvrId(room.getId());
            hostessW.setRoomId(room.getRoomId());
            hostessW.setSort(0);
            hostessW.setName("主持");
            hostessW.setUserId(room.getCreator());
            hostessW.setAccountId(room.getCreateAccountId());
            hostessW.setHostess("1");
            hostessW.setForbid("0");
            socialVoiceRoomWheatService.save(hostessW);

            //新增普通麦位
            if(category != null && category.getWheatNums()!=null && category.getWheatNums()>0){
                for(int sort=1; sort<category.getWheatNums(); sort++){
                    SocialVoiceRoomWheat wheat = new SocialVoiceRoomWheat();
                    wheat.setSvrId(room.getId());
                    wheat.setRoomId(room.getRoomId());
                    wheat.setSort(sort);
                    wheat.setHostess("0");
                    wheat.setForbid("0");
                    socialVoiceRoomWheatService.save(wheat);
                }
            }
        }else {
            if(room.getAuditStatus().equals("0")){
                throw new RestApiException(R.fail("您已有房间提交申请，请耐心等待审批结果"));
            }
            if(room.getAuditStatus().equals("1")){
                if(room.getValid().equals("0")){
                    throw new RestApiException(R.fail("您的房间被封禁，请联系管理员"));
                }
                throw new RestApiException(R.fail("您已有有效房间，请勿重复申请"));
            }
            //房间名称不能相同
            int count = count(Wrappers.<SocialVoiceRoom>lambdaQuery()
                    .eq(SocialVoiceRoom::getName, socialVoiceRoomSaveDto.getName())
                    .ne(SocialVoiceRoom::getId, room.getId()));
            if(count>=1){
                throw new RestApiException(R.fail("房间名已被使用"));
            }

            //重新提交申请
            BeanUtil.copyProperties(socialVoiceRoomSaveDto, room);
            room.setApplyNums((int)NumberUtil.add(room.getApplyNums().intValue(), 1));
            room.setAuditStatus("1");//TODO 测试，修改为审批通过
            room.setValid("1");//一般默认有效
            room.setVisible("1");//TODO 测试，修改为审批通过

            if(update(room, Wrappers.<SocialVoiceRoom>lambdaUpdate()
                    .set(SocialVoiceRoom::getRoomCategoryId, room.getRoomCategoryId())
                    .set(SocialVoiceRoom::getName, room.getName())
                    .set(SocialVoiceRoom::getIntroduction, room.getIntroduction())
                    .set(SocialVoiceRoom::getWelcomeDesc, room.getWelcomeDesc())
                    .set(SocialVoiceRoom::getThumbnail, room.getThumbnail())
                    .set(SocialVoiceRoom::getAvatar, room.getAvatar())
                    .eq(SocialVoiceRoom::getId, room.getId()))){
                //新增审批记录
                saveAudit(socialVoiceRoomSaveDto, room);
            }else {
                throw new RestApiException(R.fail("更新失败"));
            }
        }
        return room;
    }

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public SocialVoiceRoom modifyRoom(SocialVoiceRoomUpdateDto socialVoiceRoomUpdateDto) {
        SocialVoiceRoom room = getById(socialVoiceRoomUpdateDto.getId());
        if(room == null){
            throw new RestApiException(R.fail("房间不存在"));
        }
        if(!room.getAuditStatus().equals("1")){
            throw new RestApiException(R.fail("房间审核尚未通过"));
        }
        if(!room.getValid().equals("1")){
            throw new RestApiException(R.fail("房间被禁用"));
        }
        if(!room.getVisible().equals("1")){
            throw new RestApiException(R.fail("房间被关闭"));
        }
        if(room.getOfficial().equals("1")){
            if(socialVoiceRoomUpdateDto.getRoomCategoryId()==null){
                throw new RestApiException(R.fail("官方房间分类不能为空"));
            }
        }

        if(!socialVoiceRoomPermissionService.hasRoomCreatorPermission(room)){
            throw new RestApiException(R.fail("无权操作"));
        }

        if(socialVoiceRoomUpdateDto.getRoomCategoryId()!=null && socialVoiceRoomUpdateDto.getRoomCategoryId()!=0){
            //校验分类是否存在
            SocialVoiceRoomCategory category = socialVoiceRoomCategoryService
                    .getById(socialVoiceRoomUpdateDto.getRoomCategoryId());
            if(category==null){
                throw new RestApiException(R.fail("分类不存在"));
            }
        }

        //房间不能重名
        int count = count(Wrappers.<SocialVoiceRoom>lambdaQuery()
                .eq(SocialVoiceRoom::getName, socialVoiceRoomUpdateDto.getName())
                .ne(SocialVoiceRoom::getId, room.getId())
        );
        if(count>=1){
            throw new RestApiException(R.fail("房间名已被使用"));
        }

        BeanUtil.copyProperties(socialVoiceRoomUpdateDto, room);

        if(update(room, Wrappers.<SocialVoiceRoom>lambdaUpdate()
                .set(SocialVoiceRoom::getRoomCategoryId, room.getRoomCategoryId())
                .set(SocialVoiceRoom::getName, room.getName())
                .set(SocialVoiceRoom::getIntroduction, room.getIntroduction())
                .set(SocialVoiceRoom::getWelcomeDesc, room.getWelcomeDesc())
                .set(SocialVoiceRoom::getThumbnail, room.getThumbnail())
                .set(SocialVoiceRoom::getAvatar, room.getAvatar())
                .eq(SocialVoiceRoom::getId, room.getId()))){
            return room;
        }else {
            throw new RestApiException(R.fail("更新失败"));
        }
    }

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public Boolean closeOrOpenRoom(Long id, int open) {
        SocialVoiceRoom room = getById(id);
        if(room == null){
            throw new RestApiException(R.fail("房间不存在"));
        }
        if(!room.getAuditStatus().equals("1")){
            throw new RestApiException(R.fail("房间审核尚未通过"));
        }
        if(open == 1){//打开
            if(room.getVisible().equals("1")){
                throw new RestApiException(R.fail("房间已是打开状态"));
            }
        }else if(open == 2){//关闭
            if(!room.getVisible().equals("1")){
                throw new RestApiException(R.fail("房间已被关闭"));
            }
        }else {
            throw new RestApiException(R.fail("非法参数"));
        }

        if(!socialVoiceRoomPermissionService.hasRoomCreatorPermission(room.getId())){
            throw new RestApiException(R.fail("无权操作"));
        }

        room.setVisible(open==1 ? "1": "0");
        if(updateById(room)){
            return true;
        }else {
            throw new RestApiException(R.fail("更新失败"));
        }
    }

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public Boolean operateHostess(Long id, int open, long accountId) {
        SocialVoiceRoom room = checkAndGetById(id);

        if(!socialVoiceRoomPermissionService.hasRoomCreatorPermission(room)){
            throw new RestApiException(R.fail("无权操作"));
        }

        //查询主持位
        SocialVoiceRoomWheat ws = new SocialVoiceRoomWheat();
        ws.setSvrId(room.getId());
        ws.setHostess("1");
        SocialVoiceRoomWheat wheat = socialVoiceRoomWheatService.getOne(new QueryWrapper<>(ws));
        if(wheat==null){
            throw new RestApiException(R.fail("主持人麦位不存在"));
        }
        if(wheat.getForbid().equals("1")){
            throw new RestApiException(R.fail("主持人麦位被封"));
        }

        UserAccount userAccount = userAccountService.checkUserById(accountId);
        // 1:设置为主持，2取消
        if(open == 1){
            if(wheat.getAccountId()!=null && wheat.getAccountId().compareTo(userAccount.getId()) == 0){
                throw new RestApiException(R.fail("麦位用户一致，无需重复上麦"));
            }
            wheat.setAccountId(userAccount.getId());
            wheat.setUserId(userAccount.getImUserId());
        }else if(open == 2){
            wheat.setAccountId(room.getCreateAccountId());
            wheat.setUserId(room.getCreator());
        }else {
            throw new RestApiException(R.fail("非法参数"));
        }
        //更新主持人麦位
        if(socialVoiceRoomWheatService.updateById(wheat)){
            return true;
        }else {
            throw new RestApiException(R.fail("更新失败"));
        }
    }

    @Override
    public SocialVoiceRoom checkAndGetById(Long id) {
        if(id == null || id < 0){
            throw new RestApiException(R.fail("无效房间id"));
        }
        SocialVoiceRoom room = getById(id);
        if(room == null){
            throw new RestApiException(R.fail("房间不存在"));
        }
        if(!room.getAuditStatus().equals("1")){
            throw new RestApiException(R.fail("房间审核尚未通过"));
        }
        if(!room.getVisible().equals("1")){
            throw new RestApiException(R.fail("房间已被关闭"));
        }
        return room;
    }

    @Override
    public SocialVoiceRoom checkAndGetByRoomId(String roomId) {
        SocialVoiceRoom room = getBaseMapper().selectOne(Wrappers.<SocialVoiceRoom>lambdaQuery()
                .eq(SocialVoiceRoom::getRoomId, roomId));
        if(room == null){
            throw new RestApiException(R.fail("房间不存在"));
        }
        if(!room.getAuditStatus().equals("1")){
            throw new RestApiException(R.fail("房间审核尚未通过"));
        }
        if(!room.getVisible().equals("1")){
            throw new RestApiException(R.fail("房间已被关闭"));
        }
        return room;
    }

    @Override
    public SocialVoiceRoomUserRoleVo getRoomUserRole(Long id, Long accountId) {
        if(accountId==null){
            accountId = BaseContextHandler.getUserId();
        }
        UserAccount userAccount = userAccountService.checkUserById(accountId);
        SocialVoiceRoom room = checkAndGetById(id);

        SocialVoiceRoomUserRoleVo vo = new SocialVoiceRoomUserRoleVo();
        vo.setAccountId(accountId);
        vo.setImUserId(userAccount.getImUserId());
        vo.setRoomId(room.getRoomId());
        vo.setSvrId(room.getId());
        if(socialVoiceRoomPermissionService.hasRoomCreatorPermission(room)){
            vo.setRole(SocialVoiceRoomUserRoleVo.creator);
        }else if(socialVoiceRoomPermissionService.hasRoomManagerPermission(room)){
            vo.setRole(SocialVoiceRoomUserRoleVo.manager);
        }else if(socialVoiceRoomPermissionService.hasRoomHostessPermission(room)){
            vo.setRole(SocialVoiceRoomUserRoleVo.hostess);
        }else
            vo.setRole(SocialVoiceRoomUserRoleVo.normal);

        return vo;
    }

    private void saveAudit(SocialVoiceRoomSaveDto socialVoiceRoomSaveDto, SocialVoiceRoom room) {
        //新增审批记录
        SocialVoiceRoomAudit audit = new SocialVoiceRoomAudit();
        audit.setApplyReason(socialVoiceRoomSaveDto.getApplyReason());
        audit.setAuditStatus("0");
        audit.setSvr_id(room.getId());
        socialVoiceRoomAuditService.save(audit);
    }
}
